<template>
  <div class="arrange">
    <div class="cont">
      <div class="left">
        <div class="comp-class">
          <div class="title">{{ isFlow ? "编排组件" : "组件分类" }}</div>

          <div class="tabs" v-if="isFlow">
            <span class="custom">自定义编排 <i></i> </span>
            <el-link :underline="false" type="primary ">
              <span class="pl30">流程模板 </span>
              <i class="el-icon-d-arrow-right"></i>
            </el-link>
          </div>
          <div
              class="list"
              :style="{
              height: !isFlow ? 'calc(100% - 80px)' : 'calc(100% - 130px)',
            }">
            <!-- {{compClassList}} -->
            <template>
              <div
                  class="item"
                  @click="handleChange(item, i)"
                  :class="active == i && 'active'"
                  v-for="(item, i) in isFlow ? flowList : compClassList"
                  :key="i">
                <span v-if="active == i" class="active-i"></span>
                <p>
                  <!-- <img :src="item.icon" alt="" /> -->
                  <img src="../../../assets/img/operationHome/审批-应用.png" alt=""/>
                  <span>{{ item.name }}</span>
                </p>
              </div>
            </template>
          </div>
        </div>
        <div class="flow">
          <div
              class="title"
              :style="{
              backgroundColor: activeName == '流程组件' ? '#5080be' : '#06B3BA',
            }">
            <!-- {{ activeName }} -->
            流程组件
          </div>
          <div class="list" v-if="compList.length > 0">
            <div
                class="item"
                :class="activeName == '流程组件' ? 'flo' : 'other'"
                v-for="(item, i) in compList"
                :key="i"
                @mousedown="dragNode('rect', $event, item.id)">
              <!-- @mousedown="dragNode('rect', $event, item.id)" -->
              <div>
                <span :id="item.id">{{ item.name }}</span>
                <!-- <i @click="handleDelComp(i)" class="el-icon-circle-close"></i> -->
              </div>
              <!-- </el-tooltip> -->
            </div>
          </div>
          <div v-else class="empty">
            <el-empty description="暂无组件" :image-size="100"></el-empty>
          </div>
          <div class="add">
            <el-button type="primary" v-if="!isFlow" @click="addLc">
              <i class="el-icon-circle-plus-outline"></i>
              <span>新建流程组件</span>
            </el-button>
          </div>
        </div>
      </div>
      <div class="right">
        <div
            id="containerChart"
            ref="containerChart"
            :style="{
            height: 'calc(100%)',
          }"
        ></div>
        <div class="tools">
          <span
              class="tool-item"
              v-for="(item, i) in tools"
              :key="i"
              :title="item.content">
            <i :class="item.icon" class="pointer" @click="item.method"></i>
          </span>
        </div>
        <div
            class="lines"
            :style="{
            top: '10px',
            right: lineDrawer || nodeDrawer || flowDrawer ? '450px' : 0,
          }">
          <div :class="['line', 'data-line']">
            <span>数据线：</span>
            <i class="line-icon"> </i>
          </div>
          <div :class="['line', 'status-line']">
            <span>状态线：</span>
            <i class="line-icon"> </i>
          </div>
          <div :class="['line', 'control-line']">
            <span>控制线：</span>
            <i class="line-icon"> </i>
          </div>
        </div>

        <!-- <div class="mini-map-container" ref="miniMapContainerRef"></div> -->
        <!-- 节点 -->
        <NodeDrawer
            class="drawer"
            :nodeDrawer="nodeDrawer"
            v-if="nodeDrawer"
            :currentFncInfo="currentFncInfo"
            @NodesubInfo="NodesubInfo"
            :AppInfo="AppInfo"
            :edg="edg"
            :curNode="curNode"
            :lineNodeInfo="lineNodeInfo"
        ></NodeDrawer>
        <!-- 流程组件 -->
        <!-- <FlowDrawer
          class="drawer"
          :flowDrawer="flowDrawer"
          :graph="graph"
          ref="flowDrawer"
        ></FlowDrawer> -->

        <div
            class="flow-drawer"
            :style="{ right: flowDrawer ? '0' : '-450px' }">
          <div class="cont-deploy">
            <div class="right">
              <div class="title">xxx信号处理-基本信息</div>
            </div>
            <div class="r-main">
              <el-collapse v-model="activeNames">
                <el-collapse-item name="1">
                  <template slot="title">
                    <el-button round type="primary" size="small">流程缩略图
                    </el-button>
                  </template>
                  <div class="minimap" ref="minimap">
                    <div id="tooltipText" class="tooltiptext"></div>
                  </div>
                </el-collapse-item>
                <el-collapse-item name="2">
                  <template slot="title">
                    <el-button round type="primary" size="small">基本信息
                    </el-button>
                  </template>
                  <el-form :model="formData" ref="depForm" label-width="100px">
                    <el-form-item label="流程组件名称：">
                      <div>xxx信号处理</div>
                    </el-form-item>
                    <el-form-item label="组件数：">
                      <div>08</div>
                    </el-form-item>
                    <el-form-item label="内部组件名称：">
                      <div>
                        卫星网络、某解调器、数据转换引擎、BBF资源规划、信号解析、
                        BBF信号监控、BBF信号方案。
                      </div>
                    </el-form-item>
                    <el-form-item label="创建时间：">
                      <div>2021/04/25 12:56:45</div>
                    </el-form-item>
                    <el-form-item label="流程组件描述：">
                      <div>
                        XXX信号处理流程组件描述XXX信号处理流程组件描述XXX信号处
                        理流程组件描述XXX信号处理流程组件描述XXX信号处理流程组件
                        描述XXX信号处理流程组件描述
                      </div>
                    </el-form-item>
                  </el-form>
                </el-collapse-item>
              </el-collapse>
              <div class="r-bottom">
                <el-button type="primary">修改组件</el-button>
              </div>
            </div>
          </div>
        </div>

        <!-- 连线 -->
        <LineDrawer
            v-if="lineDrawer"
            class="drawer"
            @subLinInfo="subLinInfo"
            :lineDrawer="lineDrawer"
            :source="source"
            :target="target"
            :currentLin="currentLin"
        ></LineDrawer>
      </div>
    </div>

    <div class="foot">
      <el-button type="danger" size="small" @click="reset">重 置</el-button>
      <el-button type="success" size="small" @click="commplete">完成</el-button>
      <el-button type="info" size="small" @click="goBack">下一个</el-button>
    </div>

    <!--配置-->
    <ConfigDailog
        ref="configDailog"
        class="drawer"></ConfigDailog>
  </div>
</template>

<script>
import {Graph, Shape, Addon} from "@antv/x6";
import "@antv/x6-vue-shape";
import FlowDrawer from "./temp/FlowDrawer.vue";
import NodeDrawer from "./temp/NodeDrawer.vue";
import LineDrawer from "./temp/LineDrawer.vue";
import RectNode from "./temp/RectNode";
import ConfigDailog from "./temp/ConfigDailog.vue";
import {
  x6Add,
  get_getAppliesInfo,
  put_insertARelation,
  get_getPluginsByPLibrary,
  get_getAppData,
  put_addADataInfo,
  get_getARelationByAppIdAndFid,
} from "@/apis/appLC/applc";
import {
  get_selectPFunctionByPluginsId
} from "@/apis/comList/comList";
import {get_getPLibrarySelect} from "@/apis/assembly/assembly";
import {startDragToGraph} from "@/utils/Drag";

export default {
  hidden: true,
  components: {FlowDrawer, LineDrawer, NodeDrawer, ConfigDailog},
  data() {
    return {
      search: "",
      active: 0,
      isFlow: !1,
      on: 1,
      nodeDrawer: !1,
      lineDrawer: false,
      flowDrawer: !1,
      compClassList: [],
      flowList: [
        {
          name: "信号类型",
          icon: "",
          children: [
            {name: "XXX-信号处理1", desc: "组件描述", type: "rect"},
            {name: "XXX-信号处理2", desc: "组件描述", type: "rect"},
            {name: "XXX-信号处理3", desc: "组件描述", type: "rect"},
          ],
        },
        {name: "数据接收", icon: "",},
        {name: "信号接入", icon: "",},
        {name: "信号解析", icon: "",},
        {name: "资源规划", icon: "",},
        {name: "信号监控", icon: "",},
      ],
      activeNames: ["1", "2"],
      childrenActiveNames: ["11", "12", "13"],
      formData: {},
      graph: null,
      lineColor: null,
      tools: [
        {
          content: "缩小",
          method: this.handleZoomOut,
          icon: "el-icon-zoom-out",
        },
        {
          content: "放大",
          method: this.handleZoomIn,
          icon: "el-icon-zoom-in",
        },
        {
          content: "撤销",
          method: this.handleRevoke,
          icon: "el-icon-refresh-left",
        },
        {
          content: "完成",
          method: this.handleSave,
          icon: "el-icon-circle-check",
        },
      ],
      flowTopForm: {
        name: "",
        type: "",
        num: null,
        desc: "",
      },
      obstacles: [],
      currentFncInfo: null,
      appId: "",
      fAll: [],
      source: {},
      target: {},
      currentLin: "",
      AppInfo: [],
      curNode: "", //当前选中节点
      edg: "",
      pId: "",
      tzFlag: false,
      lineNodeInfo: [],
      SPosition: {},
      TPosition: {},
      appInfoData: "",
    };
  },
  created() {
    if (this.$route.query.add === "add") {
      this.getTList();
      this.appId = this.$route.query.appid;
    } else {
      this.$message.error("请先录入应用基本信息");
    }
  },
  mounted() {
    this.$nextTick(() => {
      if (this.appId) {
        this.getAppInfo(this.appId);
      } else {
        this.initAntvX6("add", null);
      }
    });
  },
  watch: {
    lineDrawer: {
      handler(newVal, oldVal) {
        console.log(newVal, oldVal);
      },
      deep: true,
    },
  },
  computed: {
    activeName() {
      if (this.compClassList.length > 0) {
        if (this.isFlow) {
          let arr = JSON.parse(JSON.stringify(this.compClassList));
          arr.shift();
          return arr.find((v, i) => i == this.active).name;
        }
        return this.compClassList.find((v, i) => i == this.active).name;
      } else {
        return [];
      }
    },
    // 组件
    compList() {
      if (this.compClassList.length > 0) {
        if (this.isFlow) {
          let arr = JSON.parse(JSON.stringify(this.compClassList));
          arr.shift();
          return arr.find((v, i) => i == this.active).children || [];
        }
        return (
          this.compClassList.find((v, i) => i == this.active).children || []
        );
      } else {
        return [];
      }
    },
  },
  methods: {
    //保存节点参数输入
    NodesubInfo(nodeInfo, csArr) {
      // console.log(nodeInfo);
      // console.log(csArr);

      let item = [];
      for (const key in nodeInfo) {
        item.push({
          ftId: key,
          aIndex: "",
          aValue: nodeInfo[key],
        });
      }
      item.forEach((res) => {
        csArr.forEach((tem) => {
          if (res.ftId == tem.fid) {
            res.aIndex = tem.wz.map(item => item.index).join(',');
          }
        });
      });

      let opt = {
        appId: this.appId,
        item,
        pId: this.pId,
      };
      put_addADataInfo(opt).then((res) => {
        console.log(res);
        let {code, msg} = res.data;
        if (code == 0) {
          this.$message.success(msg);
          this.nodeDrawer = false;
        }
      });
    },
    //addLc新建流程
    addLc() {
      this.$router.push({name: 'comphome'});
    },
    //保存线更改信息
    subLinInfo(val) {
      let arr = [];
      val.forEach((item) => {
        arr.push({
          markup: [
            {
              tagName: "rect",
              selector: "labelBody",
            },
            {
              tagName: "text",
              selector: "labelText",
            },
          ],
          attrs: {
            labelText: {
              text: " ",
              val: item,
            },
            labelBody: {
              ref: "labelText",
              refY: 3,
              refWidth: 4,
              refHeight: -6,
              fill:
                item.lxlx == 0
                  ? "#267ff7"
                  : item.lxlx == 1
                  ? "#45D9BF"
                  : "#fd9f6c",
            },
          },
          position: item.lxlx == 0 ? 0.46 : item.lxlx == 1 ? 0.5 : 0.54,
        });
      });
      this.currentLin.cell.labels = arr;
      let aRelation = [];
      val.forEach((item) => {
        let srwz = [];
        let scwz = [];
        item.wz.forEach((tem) => {
          tem.scwz.forEach((scItem) => {
            scwz.push(scItem.scwz);
          });
          tem.srwz.forEach((srItem) => {
            srwz.push(srItem.srwz);
          });
        });
        aRelation.push({
          relationLineId: this.currentLin.cell.id,
          appId: this.appId,
          relationLineSource: item.yhs,
          relationLineTarget: item.mbhs,
          relationLineType: item.lxlx * 1,
          relationOutType: item.sclx * 1,
          relationLineInputIndex: srwz.join(","),
          relationLineOutputIndex: scwz.join(","),
          relationLineSourceXaxis: this.SPosition.x,
          relationLineSourceYaxis: this.SPosition.y,
          relationLineTargetXaxis: this.TPosition.x,
          relationLineTargetYaxis: this.TPosition.y,
          relationDatetime: this.$moment().format("YYYY-MM-DD HH:mm:ss"),
        });
      });
      put_insertARelation({aRelation}).then((res) => {
        let {code, msg} = res.data;
        if (code == 0) {
          this.$message.success(msg);
          this.tzFlag = true;
          this.lineDrawer = false;
        }
      });
    },
    //查询所有组件分类 与 所属组件
    getTList() {
      get_getPLibrarySelect().then((res) => {
        let {data} = res.data;
        data.forEach((item) => {
          (item.children = []), (item.name = item.libraryName);
          get_getPluginsByPLibrary({pLibraryId: item.id}).then((res) => {
            let {code, data} = res.data;
            if (code == 0) {
              item.children = data || [];
            }
            //  { name: "XXX-流程1", desc: "组件描述", type: "rect" }
            item.children.forEach((res) => {
              res.name = res.pluginsName;
              res.desc = res.pluginsName;
              res.type = "rect";
            });
          });
        });
        this.compClassList = data;
      });
    },
    handleChange(item, i) {
      this.active = i;
    },
    // 组件关闭按钮
    handleDelComp(index) {
      // this.compList.splice(index, 1);
    },
    /**
     * 完成流程设计
     */
    commplete() {
      this.handleSave();
    },
    /**
     * 重置流程设计
     */
    reset() {
    },
    /**
     * 回退
     */
    goBack() {
      // this.$router.push("/fidlddata/flow");
    },
    handleCheckNode(item) {
      console.log(item);
    },

    //应用详情 获取数据转化 x6想要的格式
    getAppInfo(appId) {
      get_getAppliesInfo({appId}).then((res) => {
        let {data} = res.data;
        // console.log(data.amodel.amodel, "data22");
        this.tzFlag = true;
        setTimeout(() => {
          if (this.graph) {
            this.graph.dispose();
          }
          console.log(data.amodel)
          if (data.amodel) {
            this.initAntvX6("edit", JSON.parse(data.amodel.amodel));
            // store.commit("appInfoData", _this.appInfoData);
          } else {
            this.initAntvX6("edit", null);
          }
          // console.log(x6data, "x6data");
        }, 100);
      });
    },
    //初始化画布
    initAntvX6(type, data) {
      const _this = this;
      const miniMapContainerRef = this.$refs.minimap;
      // console.log(miniMapContainerRef);
      const containerRef = this.$refs.containerChart;
      const containerDom = document.getElementById("containerChart");
      Graph.registerVueComponent(
        "RectNode",
        {
          template: `
            <RectNode/>`,
          components: {
            RectNode,
          },
        },
        true
      );
      _this.graph = new Graph({
        container: containerDom,
        background: {
          color: "#F5F6FA",
        },
        history: {
          enabled: true, //历史记录
          ignoreChange: true, //ignoreChange 是否忽略属性变化
        },
        clipboard: {
          enabled: true,
          useLocalStorage: true,
        },
        selecting: true,
        panning: true, //支持平移拖拽
        snapline: true, //对齐线
        resizing: {
          //调整节点宽高
          enabled: true, //历史记录
          orthogonal: false,
        },
        autoResize: true, //自动画布大小
        mousewheel: true, //鼠标轮滚缩放

        grid: {
          size: 20, // 网格大小 10px
          visible: true, // 渲染网格背景
          type: "mesh",
          args: {
            color: "#D0D0D0",
            thickness: 1, // 网格线宽度/网格点大小
            factor: 10,
          },
        },
        highlighting: {
          magnetAvailable: _this.magnetAvailabilityHighlighter,
          magnetAdsorbed: {
            name: "stroke",
            args: {
              attrs: {
                fill: "#fff",
                stroke: "#31d0c6",
              },
            },
          },
        },
        minimap: {
          enabled: true,
          container: miniMapContainerRef,
          width: 520,
          height: 180,
          scalable: false,
        },
        connecting: {
          snap: true, //自动吸附
          allowBlank: false,
          allowLoop: false,
          highlight: true,
          connector: {
            name: "rounded",
          },
          connectionPoint: "boundary",
          createEdge() {
            return new Shape.Edge({
              datas: {},
              router: {
                name: "manhattan",
                args: {
                  offset: "center"
                },
              },
              labels: [],
              attrs: {
                line: {
                  stroke: _this.lineColor || "#4E4E4E", // stroke: "#45D9BF", stroke: "#FD9F6C",
                  strokeWidth: 2,
                  targetMarker: {
                    name: "classic",
                    size: 12,
                  },
                },
              },
            });
          },
          validateConnection({sourceView, targetView, targetMagnet}) {
            if (!targetMagnet) {
              return false;
            }
            if (targetView) {
              const node = targetView.cell;
              const portId = targetMagnet.getAttribute("port");
              console.log(node, portId, "node");
            }
            return true;
          },
        },
      });
      _this.graph.centerContent(); //画布居中
      console.log(data, "v");
      if (data) {
        _this.graph.fromJSON(data);
      }
      if (type == "edit") {
        let AllArr = this.graph.toJSON().cells;
        // let AllArr = this.appInfoData.nodes.concat(this.appInfoData.edges);
        AllArr.forEach((item) => {
          if (!this.fAll.includes(item.id) && item.shape == "rect" && item.id) {
            this.fAll.push(item.id);
          }
        });
      }

      this.graph.on("edge:connected", ({previousView, currentView}) => {
        if (previousView) {
          _this.update(previousView);
        }
        if (currentView) {
          _this.update(currentView);
        }
      });

      this.graph.on("edge:removed", ({edge, options}) => {
        if (!options.ui) {
          return;
        }

        const target = edge.getTargetCell();
        if (target) target.updateInPorts(graph);
      });

      this.graph.on("edge:mouseenter", ({edge}) => {
        edge.addTools([
          "source-arrowhead",
          "target-arrowhead",
          {
            name: "button-remove",
            args: {
              distance: -30,
            },
          },
        ]);
      });

      this.graph.on("edge:mouseleave", ({edge}) => {
        edge.removeTools();
      });

      // 双击
      this.graph.on("edge:dblclick", (e) => {
        console.log(e.cell.store.data, "e");


        this.currentLin = e;
        this.lineDrawer = false;

        setTimeout(() => {
          let edge = e.cell.store.data;
          this.nodeDrawer = !1;
          let AllArr = this.graph.toJSON().cells;
          this.source = {};
          this.target = {};
          AllArr.forEach((item) => {
            if (item.id == edge.source.cell) {
              this.SPosition = item.position;
              get_selectPFunctionByPluginsId({
                pluginsId: item.datas.pid || item.sourcePid,
              }).then((res) => {
                let {code, data} = res.data;
                if (code == 0) {
                  this.source = data;
                  this.lineDrawer = true;
                }
              });
            }
            if (item.id == edge.target.cell) {

              this.TPosition = item.position;
              get_selectPFunctionByPluginsId({
                pluginsId: item.datas.pid || item.targetPid,
              }).then((res) => {
                let {code, data} = res.data;
                if (code == 0) {
                  this.target = data;
                  this.lineDrawer = true;
                }
              });
            }
          });
        }, 16);
      });

      this.graph.on("edge:added", (e) => {
        console.log(e, "edge:added");
        this.graph.toJSON({diff: true});
        let AllArr = this.graph.toJSON().cells;
        AllArr.forEach((item) => {
          if (item.id == e.edge.id) {
            console.log(item);
          } else {
            console.log("失败");
          }
        });
      });
      this.graph.on("node:added", ({node, index, options}) => {

        let AllArr = this.graph.toJSON().cells;
        let id;
        AllArr.forEach((item) => {
          if (item.id == node.id) {
            id = item.datas.id;
          }
        });
        if (this.fAll.length > 0) {
          if (this.fAll.includes(id)) {
            this.$message.error("当前函数已存在");
            e.cell.remove();
          } else {
            this.fAll.push(id);
          }
        } else {
          this.fAll.push(id);
        }
      });
      this.graph.on("node:dblclick", ({e, x, y, node, view}) => {
        this.nodeDrawer = false;
        this.lineDrawer = false;
        let flag = false;

        setTimeout(() => {
          this.curNode = node;
          //获取函数Id
          let pId;
          let AllArr = this.graph.toJSON().cells;
          let edg = [];

          console.log(111, AllArr)


          let curArr = []; //当前组件被选择函数Id
          AllArr.forEach((item) => {
            if (item.id == node.id) {
              pId = item.datas.pid;
            }
            if (item.shape == "edge") {
              edg.push(item);
            }
          });
          this.edg = edg;
          //通过点击节点id找  边的目标id一致 切配置了线属性的  一致的获取边里选择的函数id
          this.pId = pId;
          //目标的时候 获取目标的函数ID   源的时候 获取源函数Id
          if (edg.length > 0) {
            edg.forEach((item) => {
              if (item.labels.length > 0) {
                // console.log(item);
                if (item.source.cell == node.id) {
                  curArr.push(item.labels[0].attrs.labelText.val.yhs);
                } else {
                  curArr.push(item.labels[0].attrs.labelText.val.mbhs);
                }
                flag = true;
              }
            });
          } else {
            this.$message.warning("请线连接关系线并配置相关信息");
          }

          if (flag) {
            curArr = Array.from(new Set(curArr));
            //根据APPiD与函数ID查询
            get_getAppData({appId: this.appId, pId}).then((res) => {
              let {data} = res.data;
              this.AppInfo = data;
            });
            //点击节点 查询连线关系
            get_getARelationByAppIdAndFid({
              appId: this.appId,
              pId: pId,
            }).then((res) => {
              let {code, data} = res.data;
              this.lineNodeInfo = data;
              get_selectPFunctionByPluginsId({pluginsId: pId}).then((res) => {
                let {code, data} = res.data;
                if (code === 0) {
                  // let obj = {
                  //   pamonitor: data.pamonitor,
                  //   parequire: data.parequire,
                  //   paswitch: data.paswitch,
                  //   pfunctionList: data.pfunctionList.map(item=>{
                  //     return {
                  //       ...item,
                  //
                  //     }
                  //   }),
                  //   plugins:data.plugins
                  // }
                  this.currentFncInfo = data;
                  if (node?.store?.data?.datas?.nodeName?.includes("流程")) {
                    this.flowDrawer = !0;
                    this.nodeDrawer = !1;
                  } else {
                    this.nodeDrawer = !0;
                    this.flowDrawer = !1;
                  }
                }
              });
            });
          } else {
            this.$message.warning("请配置连接线相关信息");
          }
        }, 16);
      });
      this.graph.on("node:mouseenter", ({e, x, y, node, view}) => {
        // console.log(node);
        let nodeName = node?.store?.data?.datas?.nodeName;
        node.attr({
          label: {
            fill: "#fff",
          },
          body: {
            fill: nodeName?.includes("流程") ? "#9ECDF3" : "#37CCD2",
            stroke: nodeName?.includes("流程") ? "#1E99FF" : "#14AEB0",
            strokeWidth: 2,
          },
        });
        //鼠标移入提示
        // var text = document.querySelector("#tooltipText");
        // console.log(text,'text');
        // text.innerHTML=`这是提示信息`;
        // text.style.display = 'block' ;
        //  const p1 = this.graph.localToGraph(
        //   node.store.data.position.x,
        //   node.store.data.position.y
        // );
        // 添加连接点;
        const ports = containerDom.querySelectorAll(".x6-port-body");
        this.showPorts(ports, true);

        this.obstacles.forEach((obstacle) =>
          obstacle.on("change:position", this.updateLine())
        );
        // 添加删除
        // const type = node.store.data.type;
        // const x = 300;
        let that = this;
        node.addTools(
          {
            name: "button-remove",
            args: {
              x: 160,
              y: 4,
              onClick(d) {
                let id = d.cell.id;
                console.log(id, that.fAll);
                let AllArr = this.graph.toJSON().cells;
                AllArr.forEach((item) => {
                  console.log(item, 888);
                  if (item.id == id) {
                    // that.fAll.splice(that.fAll.indexOf(item.datas.id), 1);
                    that.fAll.splice(that.fAll.indexOf(item.id), 1);
                  }
                });
                d.cell.remove();
              },
            },
          },
          "onhover" // 工具集名称，可省略);
        );
      });

      this.graph.on("node:mouseleave", ({e, x, y, node, view}) => {
        let nodeName = node?.store?.data?.datas?.nodeName;
        node.attr({
          label: {
            fill: "#333333",
          },
          body: {
            fill: nodeName?.includes("流程") ? "#EBF4FB" : "#E9F7F7",
            stroke: nodeName?.includes("流程") ? "#1E99FF" : "#84DBD5",
            strokeWidth: 2,
          },
        });
        if (node.hasTools("onhover")) {
          node.removeTools();
        }
        // 添加连接点
        const ports = containerDom.querySelectorAll(".x6-port-body");
        this.showPorts(ports, false);
      });

      this.graph.on("blank:click", ({e, x, y}) => {
        this.lineDrawer = !1;
        this.nodeDrawer = !1;
        this.flowDrawer = !1;
      });
      this.graph.history.on("undo", (e) => {
        let arr = JSON.parse(sessionStorage.getItem("hbNode"));
        //有问题  新建的id在之前的里面没有 所以不能判断
        arr.forEach((item) => {
          if (item.id == e.cmds[0].data.id) {
            if (this.fAll.includes(item.datas.id)) {
              this.fAll.splice(this.fAll.indexOf(item.datas.id), 1);
            } else {
              this.fAll.push(item.datas.id);
            }
          }
        });
      });
    },
    reloadData() {
      this.graph.paste({useLocalStorage: true});
    },

    startDrag(type, e, pid) {
      const _this = this;
      console.log(type, e, pid);
      startDragToGraph(_this.graph, type, e);
    },
    /**
     * 拖拽节点，并添加到画布中
     */
    dragNode(type, e, Pid) {
      console.log(e.target, "e");
      let id = e.target.id;
      let pid = Pid;
      let _this = this;
      let nodeName = e.target.innerText;
      let node;
      if (type == "rect") {
        node = this.createRectNode(nodeName, id, pid);
        this.obstacles.push(node);
      }
      if (type == "circle") {
        node = this.createCircleNode(nodeName);
      }
      if (type == "polygon") {
        node = this.createPolygonNode(nodeName);
      }
      const dnd = new Addon.Dnd({
        // id不会发生变化
        target: _this.graph,
        scaled: false,
        animation: true,
        getDragNode: (node) => node.clone({keepId: true}),
        getDropNode: (node) => node.clone({keepId: true}),
      });
      console.log(node, "node");
      dnd.myId = id;
      dnd.start(node, e);
      console.log(dnd, this.obstacles, "dnd");
      this.obstacles.forEach((obstacle) =>
        obstacle.on("change:position", this.updateLine())
      );
    },
    // 显示连线节点
    showPorts(ports, show) {
      for (let i = 0, len = ports.length; i < len; i = i + 1) {
        ports[i].style.visibility = show ? "visible" : "hidden";
      }
    },

    updateLine() {

    },

    /**
     * 创建画布节点
     * @param nodeType 创建画布节点的类型，rect、ellipse、polygon
     * @returns node 画布节点
     */
    createCircleNode(nodeName) {
      let _this = this;
      let node = this.graph.createNode({
        shape: "circle",
        width: 60,
        height: 60,
        attrs: {
          label: {
            text: nodeName,
            fill: "#000000",
            fontSize: 14,
            textWrap: {
              width: -20,
              height: -10,
              ellipsis: true,
            },
          },
          body: {
            fill: "#ffffff",
            stroke: "#d9d9d9",
            strokeWidth: 1,
          },
        },
        ports: {
          items: [
            {
              id: "port1",
              group: "top",
            },
            {
              id: "port2",
              group: "bottom",
            },
            {
              id: "port3",
              group: "left",
            },
            {
              id: "port4",
              group: "right",
            },
          ],
          groups: {
            top: {
              position: {
                name: "top",
              },
              attrs: {
                portBody: {
                  magnet: true,
                  r: 4,
                  stroke: "#3199FF",
                  fill: "#fff",
                  strokeWidth: 2,
                },
              },
            },
            bottom: {
              position: {
                name: "bottom",
              },
              attrs: {
                portBody: {
                  magnet: true,
                  r: 4,
                  fill: "#fff",
                  stroke: "#3199FF",
                  strokeWidth: 2,
                },
              },
            },
            left: {
              position: {
                name: "left",
              },
              attrs: {
                portBody: {
                  magnet: true,
                  r: 4,
                  fill: "#fff",
                  stroke: "#3199FF",
                  strokeWidth: 2,
                },
              },
            },
            right: {
              position: {
                name: "right",
              },
              attrs: {
                portBody: {
                  magnet: true,
                  r: 4,
                  fill: "#fff",
                  stroke: "#3199FF",
                  strokeWidth: 2,
                },
              },
            },
          },
        },
        portMarkup: [
          {
            tagName: "circle",
            selector: "portBody",
          },
        ],
      });
      return node;
    },

    /**
     * 创建多边形节点
     */
    createPolygonNode(nodeName) {
      let _this = this;
      const getUsedInPorts = (graph) => {
        const incomingEdges = graph.getIncomingEdges(this) || [];
        return incomingEdges.map((edge) => {
          const portId = edge.getTargetPortId();
          return this.getPort(portId);
        });
      };
      let node = this.graph.addNode({
        shape: "vue-shape",
        x: 40,
        y: 40,
        width: 200,
        height: 80,
        ports: {
          items: [
            {
              group: "port1",
            },
            {
              group: "port2",
            },
            {
              group: "port3",
            },
            {
              group: "port4",
            },
          ],
          groups: {
            port1: {
              position: {
                name: "top",
              },
              attrs: {
                portBody: {
                  magnet: true,
                  r: 6,
                  // stroke: "#ffa940",
                  stroke: "#3199FF",
                  fill: "#fff",
                  strokeWidth: 2,
                },
              },
            },
            port2: {
              position: {
                name: "bottom",
              },
              attrs: {
                portBody: {
                  magnet: true,
                  r: 6,
                  fill: "#fff",
                  stroke: "#3199FF",
                  strokeWidth: 2,
                },
              },
            },
            port3: {
              position: {
                name: "left",
              },
              attrs: {
                portBody: {
                  magnet: true,
                  r: 6,
                  fill: "#fff",
                  stroke: "#3199FF",
                  strokeWidth: 2,
                },
              },
            },
            port4: {
              position: {
                name: "right",
              },
              attrs: {
                portBody: {
                  magnet: true,
                  r: 6,
                  fill: "#fff",
                  stroke: "#3199FF",
                  strokeWidth: 2,
                },
              },
            },
          },
        },
        portMarkup: [
          {
            tagName: "circle",
            selector: "portBody",
          },
        ],

        component: "RectNode",
        data: {
          nodeName,
        },
      });

      return node;
    },

    /**
     * 创建矩形节点
     */
    createRectNode(nodeName, id, pid) {
      // 定义节点
      class MyShape extends Shape.Rect {
        getInPorts() {
          return this.getPortsByGroup("in");
        }

        getOutPorts() {
          return this.getPortsByGroup("out");
        }

        getUsedInPorts(graph) {
          const incomingEdges = graph.getIncomingEdges(this) || [];
          return incomingEdges.map((edge) => {
            const portId = edge.getTargetPortId();
            return this.getPort(portId);
          });
        }

        getNewInPorts(length) {
          return Array.from(
            {
              length,
            },
            () => {
              return {
                group: "in",
              };
            }
          );
        }

        updateInPorts(graph) {
          const minNumberOfPorts = 3;
          const ports = this.getInPorts();
          const usedPorts = this.getUsedInPorts(graph);
          const newPorts = this.getNewInPorts(
            Math.max(minNumberOfPorts - usedPorts.length, 1)
          );

          if (
            ports.length === minNumberOfPorts &&
            ports.length - usedPorts.length > 0
          ) {
            // noop
          } else if (ports.length === usedPorts.length) {
            // this.addPorts(newPorts);
          } else if (ports.length + 1 > usedPorts.length) {
            this.prop(
              ["ports", "items"],
              this.getOutPorts().concat(usedPorts).concat(newPorts),
              {
                rewrite: true,
              }
            );
          }
          return this;
        }
      }

      Shape.Rect.prototype.getInPorts = function () {
        return this.getPortsByGroup("in");
      };

      Shape.Rect.prototype.getOutPorts = function () {
        return this.getPortsByGroup("out");
      };

      Shape.Rect.prototype.getUsedInPorts = function (graph) {
        const incomingEdges = graph.getIncomingEdges(this) || [];
        return incomingEdges.map((edge) => {
          const portId = edge.getTargetPortId();
          return this.getPort(portId);
        });
      };

      Shape.Rect.prototype.getNewInPorts = function (length) {
        return Array.from(
          {
            length,
          },
          () => {
            return {
              group: "in",
            };
          }
        );
      };

      let type = {
        datas: {
          nodeName,
          id,
          pid,
        },
        attrs: {
          label: {
            text: nodeName,
            fill: "#333333",
            fontSize: 14,
            textWrap: {
              width: -10,
              height: -10,
              ellipsis: true,
            },
          },
          root: {
            magnet: false,
          },
          body: {
            fill: nodeName.includes("流程") ? "#EBF4FB" : "#E9F7F7", //#E9F7F7  EBF4FB
            stroke: nodeName.includes("流程") ? "#1E99FF" : "#84DBD5", //#84DBD5  # #2478EC
            strokeWidth: 2,
            rx: nodeName.includes("流程") ? 0 : 8,
            ry: nodeName.includes("流程") ? 0 : 8,
          },
        },
        ports: {
          items: [
            {
              group: "port1",
            },
            {
              group: "port2",
            },
            {
              group: "port3",
            },
            {
              group: "port4",
            },
          ],
          groups: {
            port1: {
              position: {
                name: "top",
              },
              id: pid + "luo1",
              attrs: {
                portBody: {
                  magnet: true,
                  r: 6,
                  // stroke: "#ffa940",
                  stroke: "#3199FF",
                  fill: "#fff",
                  strokeWidth: 2,
                },
              },
            },
            port2: {
              position: {
                name: "bottom",
              },
              id: pid + "luo2",
              attrs: {
                portBody: {
                  magnet: true,
                  r: 6,
                  fill: "#fff",
                  stroke: "#3199FF",
                  strokeWidth: 2,
                },
              },
            },
            port3: {
              position: {
                name: "left",
              },
              id: pid + "luo3",
              attrs: {
                portBody: {
                  magnet: true,
                  r: 6,
                  fill: "#fff",
                  stroke: "#3199FF",
                  strokeWidth: 2,
                },
              },
            },
            port4: {
              position: {
                name: "right",
              },
              id: pid + "luo4",
              attrs: {
                portBody: {
                  magnet: true,
                  r: 6,
                  fill: "#fff",
                  stroke: "#3199FF",
                  strokeWidth: 2,
                },
              },
            },
          },
        },

        portMarkup: [
          {
            tagName: "circle",
            selector: "portBody",
          },
        ],
      };
      let node = new MyShape(type).resize(200, 80);
      return node;
    },

    /**
     * 更新视图层
     */
    update(view) {
      const node = view.cell;
      console.log(node, "update");
      node.getPortsByGroup().forEach((port) => {
        const portNode = view.findPortElem(port.id, "portBody");
        view.unhighlight(portNode, {
          highlighter: this.magnetAvailabilityHighlighter,
        });
      });
      // node.updateInPorts(this.graph);
    },

    // 删除节点
    deleteNode() {
      const cell = this.graph.getSelectedCells();
      this.graph.removeCells(cell);
    },

    /**
     * 导出数据
     */
    saveData() {
      this.graph.copy(this.graph.getCells(), {
        useLocalStorage: true,
      });
      this.$message.success("保存成功！");
    },
    /**
     * 撤销
     */
    handleRevoke() {
      this.graph.undo();
    },
    /**
     * 重做
     */
    handleRefrom() {
      this.graph.redo();
    },
    /**
     * 放大
     */
    handleZoomIn() {
      this.graph.zoom(0.2);
    },
    /**
     * 缩小
     */
    handleZoomOut() {
      this.graph.zoom(-0.2);
    },
    /**
     * 全屏
     */
    handleFullSreen() {
    },
    handleSave() {
      const _this = this;
      let data = {
        appid: this.appId,
        amodel: _this.graph.toJSON(),
      };
      x6Add(data).then((res) => {
        if (res.data.code === 0) {
          console.log(res.data.data)
          if (res.data.data && res.data.data.length) {
            this.$refs.configDailog.show(res.data.data)
          }
        }
      });
      if (!_this.tzFlag) {

      } else {
        // _this.$message.error("请先建立组件连接关系");
      }
    },
  },
  beforeRouteLeave(to, from, next) {
    this.$confirm('您还未保存页面内容，是否离开当前页面?', '提示', {
      type: 'warning',
      closeOnClickModal: false,
      closeOnPressEscape: false
    }).then(() => {
      // 选择确定
      // 1、选择离开
      // 2、选择保存
      // this.saveDocument('ruleForm', false, 1).then((res) => {
      next()
      // })
    }).catch(() => {
      // 选择取消
      // this.$message({
      //   message: '',
      //   type: 'info'
      // })
      // next()
    })
  }
};
</script>

<style lang="less" scoped>
  .tooltipText {
    width: 100px;
    height: 100px;
    background: #267ef9;
    z-index: 9999;
    position: fixed;
  }

  .arrange {
    height: calc(100vh - 50px);
    width: 100%;
    display: flex;
    flex-direction: column;

    .cont {
      height: calc(100% - 40px);
      display: flex;

      .left {
        background-color: #f9fafc;
        height: 100%;
        width: 16%;
        display: flex;
        flex-direction: column;
        justify-content: space-between;
        border-left: 1px solid #f1f2f6;

        .title {
          color: #fff;
          font-size: 15px;
          height: 40px;
          line-height: 40px;
          padding-left: 10px;
        }

        .comp-class {
          height: calc(100% - 45%);

          .title {
            background-color: #4d5c71;
          }

          .tabs {
            height: 50px;
            line-height: 50px;

            .custom {
              padding-left: 18px;
              font-weight: normal;
              display: inline-block;
              width: 150px;
              color: #fff;
              font-size: 15px;
              background-color: #37ccd2;
              position: relative;

              i {
                position: absolute;
                top: 0;
                right: -24px;
                z-index: 2;
                border: 25px solid #37ccd2;
                border-width: 50px 24px 0 0;
                border-right-color: transparent;
                border-bottom-color: transparent;
              }
            }
          }

          .list {
            width: 100%;
            overflow-y: auto;

            .item {
              height: 40px;
              width: 100%;
              line-height: 40px;
              position: relative;
              padding-left: 20px;
              cursor: pointer;

              &.active {
                background-color: #edf6ff;
                color: #277cf2;
              }

              .active-i {
                position: absolute;
                top: 0;
                left: 0;
                width: 4px;
                height: 100%;
                background-color: #277cf2;
              }

              p {
                display: flex;
                align-items: center;

                span {
                  padding-left: 8px;
                }
              }
            }
          }
        }

        .flow {
          height: 45%;
          position: relative;
          display: flex;
          flex-direction: column;

          .title {
            background-color: #5080be;
          }

          .list {
            flex: 1;
            width: 100%;
            overflow-y: auto;

            .item {
              cursor: move;
              display: inline-block;
              align-self: flex-start;
              width: 130px;
              height: 40px;
              border-radius: 2px;
              padding: 0 10px;
              margin-left: 10px;
              line-height: 40px;
              margin-top: 10px;

              &.flo {
                background-color: #e5ecf4;

                &:hover {
                  background-color: #267ef9;
                }
              }

              &.other {
                background-color: #dfeded;

                &:hover {
                  background-color: #0ec6ce;
                }
              }

              &:hover {
                color: #fff;

                i {
                  display: inline-block;
                }
              }

              div {
                display: flex;
                align-items: center;
                justify-content: space-between;
                width: 100%;

                span {
                  display: inline-block;
                  overflow: hidden;
                  text-overflow: ellipsis;
                  white-space: nowrap;
                }

                i {
                  cursor: pointer;
                  padding-left: 10px;
                  font-size: 20px;
                  color: #fefffd;
                  display: none;
                }
              }
            }
          }

          .empty {
            flex: 1;
          }

          .add {
            width: 100%;

            .el-button {
              width: 100%;
            }
          }
        }
      }

      > .right {
        height: 100%;
        width: 84%;
        border-left: 1px solid #66a3f3;
        position: relative;
        overflow: hidden;

        #containerChart {
          position: relative;
          width: 100% !important;
        }

        .tools {
          transition: all 0.3s;
          position: absolute;
          left: 10px;
          top: 10px;
          z-index: 200;
          display: flex;

          .tool-item{
            padding: 4px;
            border-radius: 3px;
            background-color: #80aaff;
            color: #fff;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 18px;
            cursor: pointer;
            &+.tool-item{
              margin-left: 10px;
            }
            &:hover {
              background-color: #3584e9;
            }
          }
        }

        .lines {
          position: absolute;
          display: flex;
          transition: all 0.3s;

          .line {
            margin-right: 16px;
            border-radius: 3px;
            padding: 8px 4px;
            display: flex;
            align-items: center;

            .line-icon {
              display: inline-block;
              height: 10px;
              width: 10px;
              border-radius: 2px;
            }

            &.data-line {
              .line-icon {
                background-color: #267ff7;
              }
            }

            &.status-line {
              .line-icon {
                background-color: #45d9bf;
              }
            }

            &.control-line {
              .line-icon {
                background-color: #fd9f6c;
              }
            }
          }
        }

        .flow-top {
          padding: 10px 0;
          background-color: #fff;
          transition: all 0.3s;
        }

        .drawer {
          right: 0;
          left: auto;
          width: 450px;
          position: absolute;
        }
      }
    }

    .foot {
      background: white;
      height: 40px;
      line-height: 40px;
      padding: 0 15px;
    }

    .flow-drawer {
      background-color: #fff;
      position: absolute;
      top: 0;
      right: 0;
      transition: all 0.3s;
      height: 100%;
      width: 450px;
      overflow-y: auto;
    }

    .drawer,
    .flow-drawer {
      .cont-deploy {
        .title {
          background: #4d5c71;
          color: white;
          height: 35px;
          line-height: 35px;
          padding-left: 20px;
        }

        .r-main {
          // padding: 15px;
          height: calc(100%);
          overflow-y: auto;
          position: relative;
          background: #fff;

          /deep/ .el-collapse-item__header {
            padding-left: 20px;
          }

          /deep/ .el-collapse-item__arrow {
            margin-left: 30px;
          }

          .r-bottom {
            text-align: center;
            margin: 10px 0;
          }

          .el-collapse-item-content {
            padding: 0 20px;
          }
        }
      }
    }

    .el-empty {
      padding: 10px;
    }
  }
</style>
